/**
 * 表格转换器
 */
package cn.antia.cwin;

import java.util.*;

/**
 * @author sunkei
 * @date Jan 6, 2008
 * @time 10:55:20 PM
 */
public class NTableConvertor {
	/**
	 * 将结果转换为可输出的表格行
	 * @param fields		字段列表
	 * @param dataList			数据行
	 * @return List<List<NormalTD>>
     * @param expand expand
	 */
	public static List<List<NormalTD>> getDataList(List<Output> fields,List<Output> expand,List<Map<Cele,Object>> dataList){
		List<List<NormalTD>> rows = new ArrayList<List<NormalTD>>();
		if(dataList == null || dataList.size() < 1){
			return rows;
		}
        List<NormalTD> row;
        NormalTD td;
		String fn,fv;		//字段名,字段值
		Properties fieldValue;
		Map map;
        for (Map<Cele,Object> temp : dataList) {
            fieldValue = getFieldValues(temp);
            row = new ArrayList<NormalTD>();
            //加入字段
            for (Output gf : fields) {
                //如果是隐藏字段，不放入
                if (gf.getDispMode() != null && gf.getDispMode().equals("none")) {
                    continue;
                }
                map = gf.getValueText();
                fn = gf.getField();
                fv = fieldValue.getProperty(fn);
                td = new NormalTD();
                if (map != null && fv != null) {
                    td.setValue(map.get(fv) == null ? fv : (String) map.get(fv));
                } else {
                    td.setValue(fv);
                }
                td.setDispMode(gf.getDispMode());
                td.setGoat(gf.getGoat());
                //如果其值长度大于17，则只显示前14位，后以...代替
                if (td.getValue() != null && td.getValue().length() > 17 && (td.getDispMode() == null || !td.getDispMode().equals("pop"))) {
                    String s = td.getValue().substring(0, 14) + "...";
                    td.setGoat(s);
                    td.setDispMode("pop");
                }
                //加入title,onclick,linkUrl字段
                td.setTitle(gf.getTitle());
                td.setOnclick(gf.getOnclick());
                td.setLinkUrl(gf.getLinkUrl());
                td = setOtherValue(td, fieldValue, false);
                row.add(td);
            }
            //扩展行
            if (expand != null && expand.size() > 0) {
                //加入扩展数据
                for (Output field : expand) {
                    td = new NormalTD();
                    td.setValue(field.getText());
                    td.setTitle(field.getTitle());
                    td.setOnclick(field.getOnclick());
                    td.setLinkUrl(field.getLinkUrl());
                    td = setOtherValue(td, fieldValue, true);
                    row.add(td);
                }
            }
            rows.add(row);
        }
        return rows;
	}
	/**
	 * 设置title,onclick,linkUrl的值
	 * @param td NormalTD(已装有所有数据)
	 * @param fieldValue 行数据
	 * @return NormalTD
     * @param isExpand is expand?
	 */
	private static NormalTD setOtherValue(NormalTD td,Properties fieldValue,boolean isExpand){
		String t,o,l;	//title,onclick,linkUrl
		String v = null;
		HashSet<String> set = new HashSet<String>();
		if(isExpand){
			v = td.getValue();
		}
		t = td.getTitle();
		o = td.getOnclick();
		l = td.getLinkUrl();
		//取得隐藏在字符串中的变量
		set.addAll(getVariables(t));
		set.addAll(getVariables(o));
		set.addAll(getVariables(l));
		if(isExpand){
			set.addAll(getVariables(v));
		}
		if(set.size() > 0){
			Iterator<String> it = set.iterator();
			String ft,fv,vari;
			while(it.hasNext()){
				ft = it.next();
				fv = fieldValue.getProperty(ft);
				vari = new StringBuffer("\\{").append(ft).append("\\}").toString();
				if(fv != null){
					if(t != null)t = t.replaceAll(vari,fv);
					if(l != null)l = l.replaceAll(vari,fv);
					if(o != null){
						fv = new StringBuffer("'").append(fv).append("'").toString();
						o = o.replaceAll(vari,fv);
					}
					if(isExpand){
						if(v != null)v = v.replaceAll(vari,fv);
					}
				}
			}
		}
		td.setTitle(t);
		td.setOnclick(o);
		td.setLinkUrl(l);
		if(isExpand){
			td.setValue(v);
		}
		return td;
	}
	/**
	 * 取得隐藏在字符串(str)中的变量，放入SET
	 * @param str 字符串
	 * @return set
	 */
	private static HashSet<String> getVariables(String str){
		HashSet<String> set = new HashSet<String>();
		if(str != null){
			while(str.indexOf("{") > -1){
				str = str.substring(str.indexOf("{") + 1);
				if(str.indexOf("}") > 0){
					String v= str.substring(0, str.indexOf("}"));
					set.add(v);
					str = str.substring(str.indexOf("}"));
				}
			}
		}
		return set;
	}
	/**
	 * 取表头 fields + expands
	 * @param fields (所定义的字段)
	 * @param expands (扩展属性(扩展字段))
	 * @return List<NormalTD>
     * @param tableId table
	 */
	public static List<NormalTD> getTableTH(List<Output> fields,List<Output> expands,String tableId){
		List<NormalTD> list = new ArrayList<NormalTD>();
		NormalTD th;
        for (Output gf : fields) {
            //如果 dispMode 为 'none' 时则不显示(不加入到表头)
            if (gf.getDispMode() == null || !(gf.getDispMode().equals("none"))) {
                th = new NormalTD();
                th.setValue(gf.getText());
                th.setWidth(gf.getWidth());
                //表头TD ID 的生成规则是 table id + "_th_" + field
                th.setId((new StringBuilder(tableId).append("_th_").append(gf.getField()).toString()));
                list.add(th);
            }
        }
        if(expands != null && expands.size() > 0){
            for (Output field : expands) {
                th = new NormalTD();
                th.setValue(field.getText());
                th.setWidth(field.getWidth());
                list.add(th);
            }
        }
		return list;
	}
	/**
	 * 取得一行数据的Map映射
	 * @param eles	//行数据
	 * @return Properties
	 */
	private static Properties getFieldValues(Map<Cele,Object> eles){
		Properties map = new Properties();
		String v;
        for (Map.Entry<Cele,Object> entry:eles.entrySet()) {
            Cele ele = entry.getKey();
            v = entry.getValue().toString();
            if (ele.getField().getDbType().toLowerCase().indexOf("time") > 0) {
                if (v != null && v.length() > 16) {
                    v = v.substring(0, 16);
                }
            }
            map.setProperty(ele.getField().getFieldName(), v == null ? "" : v);
        }
        return map;
	}
}
